Imports BitSmoke.Core.Net.Connection

Imports System.Net
Imports System.Net.Sockets
Imports System.Runtime.Serialization

Namespace Core.Data.Profiles
    Public Enum UserStateConstants
        UserState_New
    End Enum

    <Serializable()> _
    Public MustInherit Class Profile
        Implements ISerializable

        Protected zGUID As Guid
        Protected zName As String
        Protected zProfileEdition As UInt16
        'TODO: portrait

        Public ReadOnly Property GUID() As Guid
            Get
                Return zGUID
            End Get
        End Property

        Public Sub New() ' parameterless constructor must exist for ISerializable support

        End Sub

        Public Sub New(ByVal pB_Default As Boolean)
            setup(pB_Default)
        End Sub

        Friend Overridable Sub setup(ByVal pB_Default As Boolean)
            If pB_Default Then
                zGUID = System.Guid.NewGuid
            End If
        End Sub

#Region " ISerializable Support "
        Private Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
            deSerialize(info, context)
        End Sub

        Friend Overridable Sub deSerialize(ByVal info As SerializationInfo, ByVal context As StreamingContext)
            zGUID = CType(info.GetValue("zGUID", GetType(Guid)), Guid)
            zName = CType(info.GetValue("zName", GetType(String)), String)
            zProfileEdition = CType(info.GetValue("zProfileEdition", GetType(UInt16)), UInt16)

        End Sub

        Public Overridable Sub GetObjectData(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext) Implements System.Runtime.Serialization.ISerializable.GetObjectData
            info.AddValue("zGUID", zGUID)
            info.AddValue("zName", zName)
            info.AddValue("zProfileEdition", zProfileEdition)

        End Sub
#End Region
    End Class

    <Serializable()> _
    Public Class UserProfile
        Inherits Profile
        Implements ISerializable
        Implements IDisposable

#Region " Private Properties "
        Private zIP As IPAddress
        Private zCommunicationPort As UInt16
        Private zState As UserStateConstants
        Private zBlacklisted As Boolean
        Private zLastSeen As DateTime
        Private zDC As DataConnection
        Private zProtocolVersion As Byte
#End Region

#Region " Public Properties "
        Public Property Blacklisted() As Boolean
            Get
                Return zBlacklisted
            End Get
            Set(ByVal value As Boolean)
                zBlacklisted = value
            End Set
        End Property

        Public Property LastSeen() As DateTime
            Get
                Return zLastSeen
            End Get
            Set(ByVal value As DateTime)
                zLastSeen = value
            End Set
        End Property

        Public Property IP() As IPAddress
            Get
                Return zIP
            End Get
            Set(ByVal value As IPAddress)
                zIP = value

                'TODO: do we need to re-listen for connections/messages?
            End Set
        End Property

        Public Property Port() As UInt16
            Get
                Return zCommunicationPort
            End Get
            Set(ByVal value As UInt16)
                zCommunicationPort = value

                'TODO: do we need to re-listen for connections/messages?
            End Set
        End Property

        Public ReadOnly Property Connection() As DataConnection
            Get
                Return zDC
            End Get
        End Property

        Public Property ProtocolVersion() As Byte
            Get
                Return zProtocolVersion
            End Get
            Set(ByVal value As Byte)
                zProtocolVersion = value
            End Set
        End Property
#End Region

#Region " Constructors "
        Public Sub New(ByVal pGUID As Guid, ByVal pIP As IPAddress, ByVal pI_CommunicationPort As UInt16, ByVal pB_ProtocolVersion As Byte)
            zGUID = pGUID
            zIP = pIP
            zCommunicationPort = pI_CommunicationPort
            zProtocolVersion = pB_ProtocolVersion
            zLastSeen = DateTime.Now

            If zProtocolVersion = DataConnection.ProtocolVersion Then
                Debug.WriteLine("making data connection to NEW user...")

                If Not zDC Is Nothing Then
                    zDC.Dispose()
                    zDC = Nothing
                End If

                zDC = New DataConnection(Me)
            Else
                'TODO: state to incompatible?
            End If
        End Sub

        Public Sub New(ByVal pB_Default As Boolean)
            setup(pB_Default)
        End Sub

        Friend Overrides Sub setup(ByVal pB_Default As Boolean)
            MyBase.setup(pB_Default)

        End Sub
#End Region

#Region " Public Methods "
        Public Sub update(ByVal pIP As IPAddress, ByVal pI_CommunicationPort As UInt16, ByVal pB_ProtocolVersion As Byte)
            zIP = pIP
            zCommunicationPort = pI_CommunicationPort
            zProtocolVersion = pB_ProtocolVersion
            zLastSeen = DateTime.Now

            If (Not Blacklisted) AndAlso (zDC Is Nothing) Then
                Debug.WriteLine("making data connection to EXISTING user (" & pIP.ToString & ":" & pI_CommunicationPort & " - " & zGUID.ToString & ")...")
                zDC = New DataConnection(Me)
            End If
        End Sub

        Public Sub acceptConnection(ByVal pTCP As TcpClient)
            Debug.WriteLine("accepted data connection...")

            If Not zDC Is Nothing Then
                zDC.Dispose()
                zDC = Nothing
            End If

            zDC = New DataConnection(Me, pTCP)
        End Sub
#End Region

#Region " ISerializable Support "
        Private Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
            deSerialize(info, context)
        End Sub

        Friend Overrides Sub deSerialize(ByVal info As SerializationInfo, ByVal context As StreamingContext)
            MyBase.deSerialize(info, context)

            zIP = CType(info.GetValue("zIP", GetType(IPAddress)), IPAddress)
            zCommunicationPort = CType(info.GetValue("zCommunicationPort", GetType(UInt16)), UInt16)
            zBlacklisted = CType(info.GetValue("zBlacklisted", GetType(Boolean)), Boolean)
            zLastSeen = CType(info.GetValue("zLastSeen", GetType(DateTime)), DateTime)
            zProtocolVersion = CType(info.GetValue("zProtocolVersion", GetType(Byte)), Byte)
        End Sub

        Public Overrides Sub GetObjectData(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext)
            MyBase.GetObjectData(info, context)

            info.AddValue("zIP", zIP)
            info.AddValue("zCommunicationPort", zCommunicationPort)
            info.AddValue("zBlacklisted", zBlacklisted)
            info.AddValue("zLastSeen", zLastSeen)
            info.AddValue("zProtocolVersion", zProtocolVersion)
        End Sub
#End Region

#Region " IDisposable Support "
        Private disposedValue As Boolean = False        ' To detect redundant calls

        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    ' free unmanaged resources when explicitly called
                    If Not zDC Is Nothing Then
                        zDC.Dispose()
                        zDC = Nothing
                    End If
                End If

                ' free shared unmanaged resources
            End If
            Me.disposedValue = True
        End Sub

        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

    End Class

    <Serializable()> _
    Public Class MyProfile
        Inherits Profile
        Implements ISerializable

#Region " Public Constants "
        Public Const FileName As String = "my.profile"
#End Region

#Region " Constructors "
        Public Sub New() ' parameterless constructor must exist for ISerializable support

        End Sub

        Public Sub New(ByVal pB_Default As Boolean)
            setup(pB_Default)
        End Sub

        Friend Overrides Sub setup(ByVal pB_Default As Boolean)
            MyBase.setup(pB_Default)

        End Sub
#End Region

#Region " ISerializable Support "
        Private Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
            deSerialize(info, context)
        End Sub

        Friend Overrides Sub deSerialize(ByVal info As SerializationInfo, ByVal context As StreamingContext)
            MyBase.deSerialize(info, context)

        End Sub

        Public Overrides Sub GetObjectData(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext)
            MyBase.GetObjectData(info, context)

        End Sub
#End Region
    End Class
End Namespace
